#include "comm.hpp"
// 是不是对应的程序，在加载的时候，会自动构建全局变量，就要调用该类的构造函数 -- 创建管道文件
// 程序退出的时候，全局变量会被析构，自动调用析构函数，会自动删除管道文件
Init init; 

string TransToHex(key_t k)
{
    char buffer[32];
    snprintf(buffer, sizeof buffer, "0x%x", k);
    return buffer;
}
int main()
{
    //1.创建共享内存的key值
    key_t k = ftok(PATH_NAME,PROJ_ID);
    assert(k != -1);
    Log("create key done",Debug) << " server key " << TransToHex(k) << endl;

    //2.创建共享内存 -- 每一次创建都要是全新的共享内存
    int shmid = shmget(k,SHM_SIZE,IPC_CREAT | IPC_EXCL | 0666);
    if(shmid == -1)
    {
        perror("shmid:");
        exit(-1);
    }

    Log("create shmid done",Debug) << " shmid " << shmid <<endl;
    // sleep(10);
    // 3.将指定的共享内存，挂接到自己的地址空间
    //第二个参数给空是让操作系统给我们随机分配共享内存地址
    char *shmaddr = (char*) shmat(shmid,nullptr,0);
    if(shmaddr == nullptr)
    {
        perror("shmaddr:");
        exit(-2);
    }
    Log("attach shm done",Debug) << " shmid " << shmid << endl;
    // sleep(10);
    //进行通信
    //结论1.只要是通信双方使用shm，一方直接向共享内存中写入数据，另一方就立马可以看到对方写的数据
    //      共享内存是所有进程间通信，速度最快的！不需要过多的拷贝！！（不需要将数据给操作系统）
    //结论2：共享内存缺乏访问控制！会带来并发问题【如果我想一定的访问控制呢？可以】
    int fd = Openfifo(FIFO_NAME,READ);
    for(; ;)
    {

        Wait(fd);//接收信号
        printf("%s\n",shmaddr);
        if(strcmp(shmaddr,"quit") == 0) break;//跳出程序代码
        // sleep(1);
    }

    // 4.将指定的共享内存，从我们自己的地址空间中去关联
    int n = shmdt(shmaddr);
    assert( n != -1);
    (void)n;
    Log("derach shm done",Debug) << " shmid " << shmid <<endl;
   // sleep(10);
    // 5. 删除共享内存，IPC_RMID即便是有进程和当下的shm挂接，依旧删除共享内存
    n = shmctl(shmid,IPC_RMID,nullptr);
    assert(n != -1);
    (void)n;//防止警告
    Log("delete shm done",Debug) << " shmid "  << shmid << endl;
    CloseFifo(fd);

    return 0;
}